﻿namespace MicroCloud.Identity.Database
{
    /// <summary>
    /// 角色种子数据初始值设定项
    /// </summary>
    [Description("系统角色种子数据")]
    public class RoleSeedDataInitializer : SeedDataInitializerBase<Role, long>
    {
        /// <summary>
        /// 初始化一个角色种子数据初始值设定项 <see cref="RoleSeedDataInitializer"/> 的新实例
        /// </summary>
        /// <param name="rootProvider"></param>
        public RoleSeedDataInitializer(IServiceProvider rootProvider)
            : base(rootProvider)
        { }

        /// <summary>
        /// 重写以提供要初始化的种子数据
        /// </summary>
        /// <param name="provider">服务提供者</param>
        /// <returns></returns>
        protected override Role[] SeedData(IServiceProvider provider)
        {
            return new[]
            {
                new Role() { Name = "Administrator", Remark = "系统管理员，系统最高权限管理角色。", IsAdmin = true, IsSystem = true }
            };
        }

        /// <summary>
        /// 重写以提供判断某个实体是否存在的表达式
        /// </summary>
        /// <param name="entity">要判断的实体</param>
        /// <returns></returns>
        protected override Expression<Func<Role, bool>> ExistingExpression(Role entity)
        {
            return m => m.Name == entity.Name;
        }

        /// <summary>
        /// 将种子数据初始化到数据库
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="provider">服务提供者</param>
        protected override void SyncToDatabase(Role[] entities, IServiceProvider provider)
        {
            if (entities?.Length > 0)
            {
                provider.BeginUnitOfWorkTransaction(provider =>
                {
                    RoleManager<Role> roleManager = provider.GetService<RoleManager<Role>>();
                    foreach (Role role in entities)
                    {
                        if (roleManager.Roles.Any(ExistingExpression(role)))
                        {
                            continue;
                        }
                        IdentityResult result = roleManager.CreateAsync(role).Result;
                        if (!result.Succeeded)
                        {
                            throw new Exception(I18N.T("同步角色种子数据 {0} 时出错：{1}", role.Name, result.ErrorMessage()));
                        }
                    }
                });
            }
        }

    }
}
